<?php

/**
 * Конфигурация приложения.
 *
 */
abstract class Kernel_Config 
{

    /**
     * Значения параметров
     *
     * @var array
     */
    static private $_values = array();

    /**
     * Возвращает значение указанного параметра. Есть три способа использования:
     * 1. $param — строка. вернет значение или $default;
     * 2. $param — ассоциативный массив. вернет массив значений параметров,
     *    соответствующих ключам массива или значения элемента массива;
     * 3. $param — числовой массив. вернет массив значений параметров,
     *    соответствующих значениям массива или $default.
     *
     * @param   string  $module
     * @param   mixed   $param
     * @param   mixed   $default
     * @return  mixed
     */
    static public function get($module, $param, $default = null) 
    {
        $params = is_array($param) ? $param : array($param => $default);
        if (is_numeric_array($params)) {
            $params = array_fill_keys($params, $default);
        }
        $values = array();
        // если параметры модуля не загружены
        if (!isset(self::$_values[$module])) {
            self::_load($module);
        }
        foreach ($params as $_param => $_default) {
            $values[$_param] = isset(self::$_values[$module][$_param])
                ? self::$_values[$module][$_param] : $_default;
        }
        return is_array($param) ? $values : reset($values);
    }

    /**
     * Загружает параметры модуля.
     *
     * @param   string  $module
     */
    static private function _load($module) 
    {
        self::_fromFile($module);
        self::_fromDb($module);
    }

    /**
     * Загружает параметры модуля из файла.
     *
     * @param   string  $module
     */
    static private function _fromFile($module) 
    {
        $path = DIRECTORY_SEPARATOR . str_camelize($module) . DIRECTORY_SEPARATOR;
        foreach (array(KERNEL_REPOSITORY, PROJECT_REPOSITORY) as $dir) {
            try {
                self::_import($module, Zend_Loader::loadFile('config.php', $dir . $path));
            } catch (Zend_Exception $e) {
                // ничего страшного :)
            }
        }
    }

    /**
     * Загружает параметры модуля из БД.
     *
     * @param   string  $module
     */
    static private function _fromDb($module) 
    {
        static $cach;
        
        if (is_null($cach)) {
            $query = '
                SELECT 
                       `module`, 
                       `prop_name` `name`, 
                       `prop_value` `value` 
                  FROM 
                       `system_config` 
                ';
            $values = database::fetchAll($query);
            if ($values) {
                while($row = array_shift($values)) {
                    $cach[$row['module']][$row['name']] = $row['value'];
                }
            } else {
                $cach = array();
            }
        }
        
        if (array_key_exists($module, $cach)) {
            self::_import($module, $cach[$module]);
        }
    }

    /**
     * Загружает значения параметров указанного модуля.
     *
     * @param   string  $module
     * @param   array   $values
     */
    static private function _import($module, $values) 
    {
        self::$_values[$module] = array_merge((array)@self::$_values[$module], $values);
    }
    
}
